home *** CD-ROM | disk | FTP | other *** search
- Unit Timer;
-
- Interface
-
- Uses Crt, Dos;
-
- procedure StartTimer;
- procedure WaitFor(tick: LongInt);
- procedure InstallFastTimer;
- procedure RestoreTimer;
-
- Implementation
-
- {$F+} { Force far mode, a good idea when mucking around with interrupts }
-
- const TIMERINTR = 8;
- PIT_FREQ = $1234DD;
-
- var BIOSTimerHandler : procedure;
- clock_ticks, counter : longint;
- curtick : longint;
-
- procedure SetTimer(TimerHandler : pointer; frequency : word);
- begin
-
- { Do some initialization }
- clock_ticks := 0;
- counter := $1234DD div frequency;
-
- { Store the current BIOS handler and set up our own }
- GetIntVec(TIMERINTR, @BIOSTimerHandler);
- SetIntVec(TIMERINTR, TimerHandler);
-
- { Set the PIT channel 0 frequency }
- Port[$43] := $34;
- Port[$40] := counter mod 256;
- Port[$40] := counter div 256;
- end;
-
- procedure CleanUpTimer;
- begin
- { Restore the normal clock frequency }
- Port[$43] := $34;
- Port[$40] := 0;
- Port[$40] := 0;
-
- { Restore the normal ticker handler }
- SetIntVec(TIMERINTR, @BIOSTimerHandler);
- end;
-
- procedure Handler; Interrupt;
- begin
-
- { DO WHATEVER WE WANT TO DO IN HERE }
- Inc(curtick);
-
- { Adjust the count of clock ticks }
- clock_ticks := clock_ticks + counter;
-
- { Is it time for the BIOS handler to do it's thang? }
- if clock_ticks >= $10000 then
- begin
-
- { Yep! So adjust the count and call the BIOS handler }
- clock_ticks := clock_ticks - $10000;
-
- asm pushf end;
- BIOSTimerHandler;
- end
-
- { If not then just acknowledge the interrupt }
- else
- Port[$20] := $20;
- end;
-
- procedure InstallFastTimer;
- begin
- SetTimer(Addr(Handler), 1000);
- end;
-
- procedure RestoreTimer;
- begin
- CleanUpTimer;
- end;
-
- procedure StartTimer;
- begin
- curtick:=0;
- end;
-
- procedure WaitFor(tick: LongInt);
- begin
- Repeat Until tick<=curtick;
- end;
-
- end.
-